using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Reflection;
using System.Text.RegularExpressions;

using SypEngine;
using SypConst.Garbage;
using SypEngine.SiteConfig;



namespace SypEngine
{
    [Serializable]
    public class SypObject : SypGarbageObject
    { 
        protected List<SypVisitor> VisitorList = null;

        public SypObject()
        {
        }

        public SypObject(SetText WriteMethod)
            : base(WriteMethod)
        {
            VisitorList = new List<SypVisitor>();
        }

        protected void AddVisitor(SypVisitor visitor)
        {
            VisitorList.Add(visitor);
        }

        public void Accept(string command, string[] parameters)
        {
            command = cleanArg(command);
            string[] cmdTab = command.Split(new char[] {SypGarbage.SUB_COMMAND_SEPARATOR});
            if (cmdTab.Length == 2)
            {
                string cmd = cmdTab[0];
                string category = cmdTab[1];
                try
                {
                    foreach (SypVisitor visitor in VisitorList)
                    {
                        Type TypeVisitor = visitor.GetType();

                        cmd = cmd.Substring(0, 1).ToUpper() + cmd.Substring(1, cmd.Length - 1).ToLower();
                        category = category.Substring(0, 1).ToUpper() + category.Substring(1, category.Length - 1).ToLower();

                        if (TypeVisitor.Name.Equals("Syp" + category + "Visitor"))
                        {
                            MethodInfo VisitorMethod = TypeVisitor.GetMethod("Visit" + cmd + "Method");
                            if (VisitorMethod != null)
                            {
                                object[] param = new object[] { this, parameters };
                                VisitorMethod.Invoke(visitor, param);
                                return;
                            }

                            SypGarbage.free(VisitorMethod);
                        }
                    }
                }
                catch (Exception e)
                {
                    OutputMethod("We catched the following error : " + e.InnerException.Message, Output.ERROR);
                    OutputMethod("Stack Trace : " + e.InnerException.StackTrace, Output.ERROR);
                    OutputMethod(string.Empty, Output.UNLOCK);
                }
                finally
                {
                    SypGarbage.free(cmd);
                    SypGarbage.free(category);
                }

            }
            else
                OutputMethod("Unknown command : " + command, Output.ERROR);
        }
    }
}
